/**************************************************************************************
*  Motor.java
*  Program demonstrating the use PWMs with LPC21xx to control DC motor.
**************************************************************************************
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY,  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL RTJ COMPUTING BE LIABLE FOR ANY CLAIM, DAMAGES
* OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Created by:
*      RTJ Computing
**************************************************************************************/
import lpc2xxx.edu.*;
import lpc2xxx.hw.*;


class Motor
{
    // duty is controlled in 0.01% increments
    final static int max = 10000;
    final static int min = 0;

    final static int stStop  = 0;
    final static int stLeft  = 1;
    final static int stRight = 2;

    final static int freq = 10000;
    final static int speedStep = 500;

    static Switch sw = new Switch();
    static GPIO gpio = new GPIO(GPIO.PORT0);

    static int dutyL = min;
    static int dutyR = min;
    static int rotState = stStop;
    
    static void main(String[] args) 
    {
        Console.println("");
        Console.println("LPC21xx DC motor control with PWM4/PWM6");
        Console.println("This program is for use with LPC2148 Education board");
        Console.println("Jumper settings:");
        Console.println("  connect    J49,J51,J53\r\n");
        Console.println("Joystick usage:");
        Console.println("  left/right - change motor direction");
        Console.println("  up/down    - change rotaion speed");
        Console.println("  center     - stop motor");
        Console.println("To exit press ESC");
        Console.println("");

        sw.start();

        PWM.init(PWM.PWM4 | PWM.PWM6, freq);
        gpio.config(0, 0xFFCFFFFF, 0);
        gpio.dirOut(GPIO.P10);

        stopMotor();

        while (true)
        {
            if (Console.getKey() == Console.ESC)
                break;

            boolean dutyChanged = false;
            if (sw.left() && rotState != stLeft)
            {
                stopMotor();
                rotState = stLeft;
                gpio.set(GPIO.P10);
                dutyChanged = true;
            }
            else if (sw.right() && rotState != stRight)
            {
                stopMotor();
                rotState = stRight;
                gpio.set(GPIO.P10);
                dutyChanged = true;
            }
            else if (sw.up())
            {
                if (rotState == stLeft && dutyL < max)
                {
                    dutyL += speedStep;
                    dutyChanged = true;
                }
                else if (rotState == stRight && dutyR < max)
                {
                    dutyR += speedStep;
                    dutyChanged = true;
                }
            }
            else if (sw.down())
            {
                if (rotState == stLeft && dutyL > min)
                {
                    dutyL -= speedStep;
                    dutyChanged = true;
                }
                else if (rotState == stRight && dutyR > min)
                {
                    dutyR -= speedStep;
                    dutyChanged = true;
                }
            }
            else if (sw.center())
                stopMotor();

            if (dutyChanged)
            {
                setDuty();
                delay(200);
            }
        }
        stopMotor();
    }

    static void setDuty()
    {
        PWM.duty(PWM.PWM4, dutyL);
        PWM.duty(PWM.PWM6, dutyR);
        PWM.apply();

        switch (rotState)
        {
            case stLeft:
                Console.print("\rLeft: " + Integer.toString(dutyL / 100) + "%     ");
                break;
            case stRight:
                Console.print("\rRight: " + Integer.toString(dutyR / 100) + "%    ");
                break;
            default:
                Console.print("\rMotor stopped  ");
        }
    }

    static void stopMotor()
    {
        while (dutyL > speedStep || dutyR > speedStep)
        {
            if (dutyL > 0)
                dutyL -= speedStep;
            if (dutyR > 0)
                dutyR -= speedStep;
            setDuty();
            delay(50);
        }
        dutyL = min;
        dutyR = min;
        rotState = stStop;
        setDuty();
        gpio.clear(GPIO.P10);
    }

    static void delay(int ms)
    {
        try
        {
            Thread.sleep(ms);
        }
        catch (InterruptedException e) {}
    }
}

